﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml;
using System.Xml.Linq;
using Yule8xCommon.Applib;
using Yule8xCommon.Db;
using Yule8xModel;
using Yule8xWechat.Applib;

namespace Yule8xWechat
{
    public partial class WxEventApi : System.Web.UI.Page
    {
        const string Token = "yule8xtoken";
        const string EncodingAESKey = "eelz0Fa36uv4ztEBJSYtlN84wEGQC8XDelo5smXhpQ4";
        const string serverUri = "http://wx.34537.com/";
        protected void Page_Load(object sender, EventArgs e)
        {

            if (RequestUtil.GetString("menu").Length > 0)
            {
                this.CreateMenu();
            }
            string echostr = RequestUtil.GetString("echostr");
            if (echostr.Length > 0)
            {
                this.Valid();
            }
            else
            {
                this.parseMsg();
            }
        }
        private void CreateMenu()
        {
            string token = WechatUtil.GetToken();
            string url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token;
            string menu = RuntimeDataUtil.GetMenuText(Reslib.Menu);
            string msg = HttpUtil.HttpPost(url, menu.Replace('\'', '\"'));
            LogUtil.Instance.WriteInfo("[微信事件消息托管接口-CreateMenu] " + msg);
            //Response.Write(msg);
        }
        private void Valid()
        {
            string echostr = RequestUtil.GetString("echostr");
            string errmsg = "";
            if (echostr.Length > 0)
            {
                if (this.checkSignature())
                {
                    LogUtil.Instance.WriteInfo("[微信事件消息托管接口-Valid] 签名成功");
                    Response.Write(echostr);
                    Response.End();
                }
                else
                {
                    errmsg = "[微信事件消息托管接口-Valid]签名不正确 " + echostr;
                    Response.Write(errmsg);
                    LogUtil.Instance.WriteInfo(errmsg);
                }
            }
            else
            {
                errmsg = "[微信事件消息托管接口-Valid] 签名为空";
                Response.Write(errmsg);
                LogUtil.Instance.WriteInfo(errmsg);
            }
        }
        private void parseMsg()
        {
            string welcomestr = RuntimeDataUtil.GetWelcomeText("欢迎来到八星娱乐公众号, 好兄弟，一起玩八星游戏!");

            // 接收消息
            Stream s = Request.InputStream;
            byte[] b = new byte[s.Length];
            s.Read(b, 0, (int)s.Length);
            string postStr = Encoding.UTF8.GetString(b);
            if (string.IsNullOrEmpty(postStr))
            {
                LogUtil.Instance.WriteInfo(welcomestr);
                Response.Write(welcomestr);
                Response.End();
                return;
            }
            LogUtil.Instance.WriteInfo("[微信事件消息托管接口-postStr] " + postStr);
            XElement xml = XElement.Parse(postStr);

            string toUsername = XMLUtil.GetNodeValue(xml, "ToUserName");
            string fromUsername = XMLUtil.GetNodeValue(xml, "FromUserName");
            string msgType = XMLUtil.GetNodeValue(xml, "MsgType");
            string eventStr = XMLUtil.GetNodeValue(xml, "Event");
            string rec = XMLUtil.GetNodeValue(xml, "Recognition");
            string mid = XMLUtil.GetNodeValue(xml, "MediaId");
            string url = XMLUtil.GetNodeValue(xml, "Url");
            string content = XMLUtil.GetNodeValue(xml, "Content").Trim();
            string eventKey = XMLUtil.GetNodeValue(xml, "EventKey");
            int createTime = StringUtil.ToInteger(XMLUtil.GetNodeValue(xml, "CreateTime"));
            string contentStr = string.Empty;
            string sqlstmt = string.Empty;
            string returnMsg;
            switch (msgType)
            {
                case "text":
                    contentStr = "收到文字消息,内容是 " + content;
                    Dictionary<string, string> mimianhao = RuntimeDataUtil.GetKeywordData(string.Format("开单888888:https://wx.34537.com/XAgent/guid.html{0}测起来666:http://wxcs.34537.com/Test/Default.aspx", Environment.NewLine));
                    if (mimianhao.ContainsKey(content))
                    {
                        this.outputText(fromUsername, toUsername, mimianhao[content]);
                    }
                    break;
                case "image":
                    contentStr = "收到图片消息,MediaId=" + mid;
                    string picurl = XMLUtil.GetNodeValue(xml, "PicUrl");
                    string mediaid = XMLUtil.GetNodeValue(xml, "MediaId");
                    break;
                case "voice":
                    contentStr = "收到语音消息,MediaId=" + mid + ", 内容是" + rec;
                    break;
                case "video":
                    contentStr = "收到视频消息,MediaId=" + mid;
                    break;
                case "location":
                    string lotitude_x = XMLUtil.GetNodeValue(xml, "Location_X");
                    string longitude_y = XMLUtil.GetNodeValue(xml, "Location_Y");
                    contentStr = "收到地理位置消息, 经度:" + lotitude_x + ", 纬度:" + longitude_y;
                    string scale = XMLUtil.GetNodeValue(xml, "Scale");
                    string label = XMLUtil.GetNodeValue(xml, "Label");
                    break;
                case "link":
                    contentStr = "收到链接消息, 链接为" + url;
                    break;
                case "event":
                    switch (eventStr)
                    {
                        // subscribe,SCAN,CLICK,LOCATION,VIEW
                        case "subscribe":
                            LogUtil.Instance.WriteInfo(string.Format("[用户关注微信号并注册(扫描推广码)] eventKey={0}, openid={1}", eventKey, fromUsername));
                            this.CreateMenu();
                            contentStr = welcomestr; // 收到关注微信号事件.
                            // str: qrscene_ogQPs1X6bAtttToMgBcUxHNLlRzc
                            // id:  qrscene_1
                            string promotion_tag = string.Empty;
                            if (eventKey.IndexOf("qrscene_") > -1) // 这是推广二维码
                            {
                                string scene_value = eventKey.Substring("qrscene_".Length);
                                int parent1_uid;
                                if (int.TryParse(scene_value, out parent1_uid))
                                {
                                    // 解析并提取推广码中附带的上级uid，提取当前用户openid
                                    parent1_uid = int.Parse(scene_value);
                                    int dailycardcount = AppConf.ReferralUserDailyMaxCardCount; // 配置参数中的用户每天推广领卡最大数量
                                    int eachcardcount = AppConf.ReferralUserEachCardCount; // 配置参数中的每推广一个用户可获得的房卡数量
                                    UserModels.UserRegistByQrcode(fromUsername, createTime, parent1_uid, dailycardcount, eachcardcount, "bozhong", out returnMsg);
                                }
                                else
                                {
                                    promotion_tag = scene_value;
                                }
                            }
                            else
                            {
                                UserModels.UserRegistWithoutQrcode(fromUsername, createTime, out returnMsg);
                            }
                            // 重新刷新关注时间
                            sqlstmt = string.Format("update t_user set subscribe = 1, subscribe_time={0}, remark='{2}' where openid_biz = '{1}'", createTime, fromUsername, promotion_tag);
                            DbFactory.Init(AppInfo.conn_yule8x_agent).ExecuteNonQuery(sqlstmt);
                            this.outputText(fromUsername, toUsername, contentStr);
                            break;
                        case "unsubscribe":
                            contentStr = "收到取消关注微信号事件";
                            // 更新用户字段
                            UserModels.UserUnsubscribe(fromUsername, createTime, out returnMsg);
                            break;
                        case "CLICK":
                            switch (eventKey)
                            {
                                case "V1001_DOWNLOAD":
                                    this.outputImage(fromUsername, toUsername, serverUri + "Skin/Theme/Images/downloadapk.png");
                                    return;
                                case "V1001_CONTACT":
                                    break;
                            }
                            contentStr = "收到点击菜单消息,Key=" + eventKey;
                            break;
                        case "SCAN":
                            string ticket = XMLUtil.GetNodeValue(xml, "Ticket");
                            contentStr = "收到扫描二维码消息,Key=" + eventKey;
                            break;
                        case "LOCATION":
                            string latitude = XMLUtil.GetNodeValue(xml, "Latitude");
                            string longitude = XMLUtil.GetNodeValue(xml, "Longitude");
                            string precision = XMLUtil.GetNodeValue(xml, "Precision");
                            contentStr = "收到点击地理位置消息,Key=" + eventKey;
                            break;
                        case "VIEW":
                            contentStr = "收到点击视图菜单消息,Key=" + eventKey;
                            break;
                    }
                    break;
            }
            //this.outputText(fromUsername, toUsername, contentStr);
            LogUtil.Instance.WriteInfo("[微信事件消息托管接口-contentStr] " + contentStr);
        }


        /**
         * 生成向用户发送的文字信息
         * @param string $content
         * @return string xml字符串
         */
        public void outputText(string fromUserName, string toUserName, string content)
        {
            if (string.IsNullOrEmpty(content))
            {
                content = "空消息";
            }
            string text = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{3}]]></Content></xml>", fromUserName, toUserName, DateTimeUtil.ConvertDateTimeInt(DateTime.Now), content);
            LogUtil.Instance.WriteInfo("[微信事件消息托管接口-outputText] " + text);
            Response.ContentType = "application/xml";
            Response.Write(text);
            Response.End();
        }
        public void outputImage(string fromUserName, string toUserName, string picurl)
        {
            if (string.IsNullOrEmpty(picurl))
            {
                return;
            }
            string text = string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime><MsgType><![CDATA[image]]></MsgType><PicUrl><![CDATA[{3}]]></PicUrl><MsgId><![CDATA[{2}]]></MsgId></xml>", fromUserName, toUserName, DateTimeUtil.ConvertDateTimeInt(DateTime.Now), picurl);
            LogUtil.Instance.WriteInfo("[微信事件消息托管接口-outputText] " + text);
            Response.ContentType = "application/xml";
            Response.Write(text);
            Response.End();
        }
        /**
         * 验证url来源是否证确
         * @return boolean
         * @throws Exception
         * @since 1.0 2017-4-13
         */
        private bool checkSignature()
        {
            string signature = RequestUtil.GetString("signature");
            string timestamp = RequestUtil.GetString("timestamp");
            string nonce = RequestUtil.GetString("nonce");

            string[] tmpArr = new string[] { Token, timestamp, nonce };
            Array.Sort(tmpArr);
            string tmpStr = string.Join("", tmpArr);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1").ToLower();
            if (tmpStr == signature)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}